using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Data;
using System.Data.Common;
using System.Data.Odbc;
using System.Data.SqlClient;
using System.Data.SQLite;
using System.Diagnostics;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Windows.Forms.DataVisualization.Charting;
using HslCommunication;
using HslCommunication.BasicFramework;
using HslCommunication.Profinet.Siemens;
using 自定图标类;
using static System.Net.Mime.MediaTypeNames;
using static System.Windows.Forms.VisualStyles.VisualStyleElement;

namespace PLC数据采集
{
    public partial class Form1 : Form
    {
        #region 通信字段
        SiemensS7Net SimaticS7Net;
        #endregion
        #region 图表字段
        List<Chart> charts= new List<Chart>();
        List<chartClass> chartClasses= new List<chartClass>();
        List<string> st = new List<string>();
        List<string> type = new List<string>();
        List<int> ints= new List<int>(); 
        #endregion
        public Form1()
        {
            InitializeComponent();
            //Control.CheckForIllegalCrossThreadCalls = false;
        }

        private void 连接_Click(object sender, EventArgs e)
        {
            SimaticS7Net = new SiemensS7Net(SiemensPLCS.S1500, IP地址.Text);//设定连接目标
            OperateResult connect = SimaticS7Net.ConnectServer();//建立长连接
            //判断是否长连接成功
            if (connect.IsSuccess)
            {
                连接btn.Enabled= false;
                断开btn.Enabled = true;
                //MessageBox.Show(StringResources.Language.ConnectedSuccess);
            }
            else
            {
                MessageBox.Show(StringResources.Language.ConnectedFailed);
            }

        }

        private void 断开_Click(object sender, EventArgs e)
        {
            OperateResult connect = SimaticS7Net.ConnectClose();
            if (connect.IsSuccess)
            {
                连接btn.Enabled = true;
                断开btn.Enabled = false;
                MessageBox.Show("断开成功");
            }
            else
            {
                MessageBox.Show("断开失败");
            }
        }

        private void 保存_Click(object sender, EventArgs e)
        {
            保存dataview();
        }

        private void 启动btn_Click(object sender, EventArgs e)
        {
            停止 = false;
            //获取DataGridView中每行的数据
            st.Clear();
            for (int i = 0; i < dataGridView1.Rows.Count - 1; i++)
            {
                st.Add(dataGridView1.Rows[i].Cells[0].Value.ToString());
                type.Add(dataGridView1.Rows[i].Cells[1].Value.ToString());
            }
            tabPage5.Controls.Clear();
            charts.Clear();
            for (int i = 0; i < st.Count; i++)
            {
                chartClass c = new chartClass(st[i], type[i]);
                chartClasses.Add(c);
                charts.Add(c.返回图表());
                charts[i].Dock = DockStyle.Top;
                tabPage5.Controls.Add(charts[i]);
            }
            值 = new int[st.Count];
            for (int i = 0; i < st.Count; i++)
            {
                Thread TH = new Thread(获取数据);
                TH.Name = i.ToString();
                TH.Start();
            }
            Task tsk2 = new Task(实时图表);
            tsk2.Start();
        }
        int[] 值;
        bool 停止 = true;
        void 实时图表()
        {
            while (!停止)
            {
                Thread.Sleep(1);
                int I = 0;
                if (值.Length == st.Count)
                {
                    foreach (var s in st)
                    {
                        Invoke(new Action(() => {
                            if (charts[I].Series[0].Points.Count >= 500)
                            {
                                charts[I].Series[0].Points.RemoveAt(0);
                            }
                            charts[I].Series[0].Points.AddY(值[I]);
                        }));
                        I++;
                    } 
                }
                I = 0; 
            }
        }
        void 获取数据()
        {
            int i = Convert.ToInt32(Thread.CurrentThread.Name);
            switch (type[i])
            {
                case "bool":
                    while (!停止)
                    {
                        Thread.Sleep(10);
                        值[i] = Convert.ToInt32(SimaticS7Net.ReadBool(st[i]).Content);
                    }
                    break;
                case "int":
                    while (!停止)
                    {
                        Thread.Sleep(10);
                        值[i] = Convert.ToInt32(SimaticS7Net.ReadInt32(st[i]).Content);
                    }
                    break;
            }
        }
        //新建一个需要连接的数据库
        SQLiteConnection 数据库连接;
        void 连接数据库()
        {
            File.Delete("AA.db");
            数据库连接 = new SQLiteConnection("Data Source=AA.db;Version=3;");//没有数据库则自动创建
            数据库连接.Open();//打开数据库,生成db文件
        }
        void 新建表单(int 输入int)
        {
            string 表单名 = st[输入int];
            //新建表单
            SQLiteCommand command = new SQLiteCommand();//新建命令对象
            command.Connection = 数据库连接;
            command.CommandText = "CREATE TABLE \"" + 表单名 + "\" (值 INTEGER);";
            command.ExecuteNonQuery();
            command.Dispose();
        }
        void 写入数据库(int 输入int)
        {
            
        }
        void 循环写入数据库(int 输入int)
        {
            连接数据库();
            新建表单(0);
            string 表单名 = st[输入int];
            SQLiteCommand command = new SQLiteCommand();//新建命令对象
            command.Connection = 数据库连接;//和数据库连接
            SQLiteTransaction tr = 数据库连接.BeginTransaction();//事务开始
            int j = 0;
            while (!停止)
            {
                Thread.Sleep(10);
                command.CommandText = "INSERT INTO \"" + 表单名 + "\"(值) VALUES('" + 值[输入int] + "')";
                command.ExecuteNonQuery();
                if (j>=50)
                {
                    tr.Commit();//提交事务
                    tr = 数据库连接.BeginTransaction();//事务开始
                    j = 0;
                }
                else
                {
                    j++;
                }
            }
            tr.Commit();//提交事务
            command.Dispose();
            数据库连接.Dispose();
        }
        public void 保存dataview()
        {
            //实例化一个保存文件对话框
            SaveFileDialog sf = new SaveFileDialog();
            //设置文件保存类型
            sf.Filter = "txt文件|*.txt";
            //如果用户没有输入扩展名，自动追加后缀
            sf.AddExtension = true;
            //设置标题
            sf.Title = "写文件";
            //如果用户点击了保存按钮
            if (sf.ShowDialog() == DialogResult.OK)
            {
                //实例化一个文件流--->与写入文件相关联
                FileStream fs = new FileStream(sf.FileName, FileMode.Create);
                //实例化一个StreamWriter-->与fs相关联
                StreamWriter sw = new StreamWriter(fs);
                //开始写入
                if (this.dataGridView1.Rows.Count < 1)
                {
                    MessageBox.Show("没有数据！导出失败！", "提示", MessageBoxButtons.OK, MessageBoxIcon.Information);

                }
                else
                {
                    string st = "";
                    for (int i = 0; i < this.dataGridView1.Rows.Count - 1; i++)
                    {
                        for (int j = 0; j < this.dataGridView1.Columns.Count; j++)
                        {
                            st += this.dataGridView1.Rows[i].Cells[j].Value.ToString()+@";";
                        }
                        sw.WriteLine(st);
                        st = "";
                    }
                    //sw.Write(this.textBox1.Text);
                    //清空缓冲区
                    sw.Flush();
                    //关闭流
                    sw.Close();
                    fs.Close();
                    MessageBox.Show("保存成功！", "提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
                }
            }


        }
        public void 加载到dataview中()
        {
            FileDialog fd = new OpenFileDialog();
            if (fd.ShowDialog() == DialogResult.OK)
            {
                string[] list;
                string st = fd.FileName;
                using (StreamReader sr = new StreamReader(st))
                {
                    int i = 0;
                    while (!sr.EndOfStream)
                    {
                        list = sr.ReadLine().Split(';');
                        int index = this.dataGridView1.Rows.Add();
                        for (int j = 0; j < list.Length-1; j++)
                        {
                            this.dataGridView1.Rows[index].Cells[j].Value = list[j];
                        }
                        i++;
                    }
                }
            }
            fd.Dispose();
        }
        private void 停止btn_Click(object sender, EventArgs e)
        {
            停止 = true;
        }

        private void 加载Btn_Click(object sender, EventArgs e)
        {
            加载到dataview中();
        }

        private void Form1_FormClosed(object sender, FormClosedEventArgs e)
        {
            停止 = true;
            Environment.Exit(0);
        }
        List<string> 表单名 = new List<string>();
        List<chartClass> 历史图表列表 = new List<chartClass>();
        List<Chart> 历史图表= new List<Chart>();
        SQLiteConnection 历史数据库;//新建数据库连接对象
        private void 打开历史btn_Click(object sender, EventArgs e)
        {
            OpenFileDialog op = new OpenFileDialog();//打开文件对话对象
            if (op.ShowDialog() == DialogResult.OK)//打开选择文件框
            {
                string s = op.FileName;//获取文件路径及名称
                历史数据库 = new SQLiteConnection("Data Source = "+s+"; Version = 3;");//设定连接数据库的名称和版本;
                历史数据库.Open(); //连接数据库
            }
            else
            {
                return;
            }
            SQLiteCommand command = new SQLiteCommand(@"select name from sqlite_master where type='table' order by name;", 历史数据库);//连接数据库并执行指令;
            SQLiteDataReader dataReader= command.ExecuteReader();//新建datareader对象;
            表单名.Clear();//清空数据
            while (dataReader.Read())//重复读取表单名,知道读取结束;
            {
                表单名.Add(dataReader["name"].ToString());//获取表单的名字
            }
            dataReader.Close();//必须关闭不然后面读取报错;
            历史图表列表.Clear() ;//清空数据
            历史图表.Clear();//清空数据
            tabPage4.Controls.Clear();//清空页面中已有的图表
            for (int i = 0; i < 表单名.Count; i++)
            {
                string[] ii = 表单名[i].Split(';');//数据库定的是:   M0.0;bool
                chartClass c = new chartClass(ii[0], ii[1]);//新建图表对象
                历史图表列表.Add(c);//存储进历史图表列表里面
                历史图表.Add(c.返回图表());//存进历史图表里面
                历史图表[i].Dock = DockStyle.Top;//设定为顶部靠齐
                tabPage4.Controls.Add(历史图表[i]);//图表添加至tabpage页面
            }

            string sql = "SELECT  * FROM\"" + 表单名[0] +"\"  order by 序号 desc;";//倒序
            command = new SQLiteCommand(sql, 历史数据库);//指定的数据库并执行指令;
            dataReader = command.ExecuteReader();//定义数据读取器rdr获取传回的数据
            dataReader.Read();//读取第一行数据;
            string classname = dataReader["序号"].ToString();//根据列名获取值

            hScrollBar1.Maximum = Convert.ToInt32(classname);
            dataReader.Close();
            总点.Clear();
            for (int i = 0; i < 表单名.Count; i++)
            {
                总点.Add(null);
            }
            for (int i = 0; i < 表单名.Count; i++)
            {
                Thread th = new Thread(更新历史数据);
                th.Name = i.ToString();
                th.Start();
            }
        }
        List<List<int>> 总点 = new List<List<int>>();
        void 更新历史数据()
        {
            int 输入int = Convert.ToInt32(Thread.CurrentThread.Name);
            List<int> list是是是 = new List<int>();
            int 上限 = 0, 下限 = 0;
            下限 = Convert.ToInt32(hScrollBar1.Value);
            上限 = 下限 + 500;
            string sql = "SELECT * FROM \"" + 表单名[输入int] +"\" WHERE [序号]<=" + 上限 + " AND [序号]>=" + 下限;
            SQLiteCommand command = new SQLiteCommand(sql, 历史数据库);
            SQLiteDataReader sqlrd = command.ExecuteReader();
            while (sqlrd.Read())
            {
                list是是是.Add(Convert.ToInt32(sqlrd["值"]));
            }
            总点[输入int] = list是是是;
            Invoke(new Action(() =>
            {
                历史图表[输入int].Series[0].Points.DataBindY(总点[输入int]);
            }));
        }

        private void hScrollBar1_ValueChanged(object sender, EventArgs e)
        {
            for (int i = 0; i < 表单名.Count; i++)
            {
                Thread th = new Thread(更新历史数据);
                th.Name = i.ToString();
                th.Start();
            }
        }
    }
}
